// Fill out your copyright notice in the Description page of Project Settings.


#include "Character/EnemyCharacter.h"

#include "StarrySkyGameplayTags.h"
#include "AbilitySystem/StarrySkyAbilitySystemComponent.h"
#include "AbilitySystem/StarrySkyAttributeSet.h"
#include "Components/WidgetComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "StarrySky/StarrySky.h"
#include "UI/Widgets/StarrySkyUserWidget.h"

AEnemyCharacter::AEnemyCharacter()
{
	GetMesh()->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
	//初始化能力系统组件
	AbilitySystemComponent=CreateDefaultSubobject<UStarrySkyAbilitySystemComponent>("AbilitySystemComponent");
	AbilitySystemComponent->SetIsReplicated(true);
	//初始化属性集
	AttributeSet=CreateDefaultSubobject<UStarrySkyAttributeSet>("AttributeSet");
	//创建生命值条的页面小部件组件
	HealthBar=CreateDefaultSubobject<UWidgetComponent>("HealthBar");
	HealthBar->SetupAttachment(GetRootComponent());

	//停止通过AIController控制的旋转
	bUseControllerRotationPitch=false;
	bUseControllerRotationYaw=false;
	bUseControllerRotationRoll=false;
	//使用运动组件控制旋转
	GetCharacterMovement()->bUseControllerDesiredRotation=true;
	BaseWalkSpeed=250.f;
}

void AEnemyCharacter::HighlightActor()
{
	//添加自定义深度
	GetMesh()->SetRenderCustomDepth(true);
	GetMesh()->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
	Weapon->SetRenderCustomDepth(true);
	Weapon->SetCustomDepthStencilValue(CUSTOM_DEPTH_RED);
}

void AEnemyCharacter::UnHighlightActor()
{
	//取消描边
	GetMesh()->SetRenderCustomDepth(false);
	Weapon->SetRenderCustomDepth(false);
}

int32 AEnemyCharacter::GetPlayerLevel()
{
	return Level;
}

void AEnemyCharacter::BeginPlay()
{
	Super::BeginPlay();
	GetCharacterMovement()->MaxWalkSpeed=BaseWalkSpeed;
	//初始化能力系统
	InitAbilityActorInfo();
	UStarrySkyUserWidget* Overlay=Cast<UStarrySkyUserWidget>(HealthBar->GetUserWidgetObject());
	if(Overlay)
	{
		Overlay->SetWidgetController(this);
	}

	//获取属性集，广播血量和最大血量
	const UStarrySkyAttributeSet* StarrySkyAs=Cast<UStarrySkyAttributeSet>(AttributeSet);
	if(StarrySkyAs)
	{
		//能力组件绑定血量的变化,监听当GetHealthAttribute方法属性改变的时候，调用一个Lambda，将属性广播出去
		AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(StarrySkyAs->GetHealthAttribute()).AddLambda
		(
			[this](const FOnAttributeChangeData& Data)
			{
				OnHealthChanged.Broadcast(Data.NewValue);
			}
		);
		//广播最大血量
		AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(StarrySkyAs->GetMaxHealthAttribute()).AddLambda
		(
			[this](const FOnAttributeChangeData& Data)
			{
				OnMaxHealthChanged.Broadcast(Data.NewValue);
			}
		);
		//初始化广播默认属性
		OnHealthChanged.Broadcast(StarrySkyAs->GetHealth());
		OnMaxHealthChanged.Broadcast(StarrySkyAs->GetMaxHealth());
	}
}

void AEnemyCharacter::InitAbilityActorInfo()
{
	//设置ASC初始化的拥有角色和化身角色
	check(AbilitySystemComponent);
	AbilitySystemComponent->InitAbilityActorInfo(this,this);
	Cast<UStarrySkyAbilitySystemComponent>(AbilitySystemComponent)->AbilityActorInfoSet();
	//设置号能力系统组件后，绑定晕眩标签的监听
	if (HasAuthority())
	{
		InitializeDefaultAttributes();
	}
}
